const fs = require('fs');

const updateDBFile = (filePath, handlers) => {
  const { onReadError, onReadOver, onWriteError, onWriteOver } = handlers;
  fs.readFile(filePath, 'utf8', (err, dataStr) => {
    if (err) {
      onReadError?.(error);
      return;
    }
    const data = dataStr ? JSON.parse(dataStr) : [];
    const readOverResult = onReadOver?.(data);
    if (readOverResult !== false) {
      const newData = readOverResult || [];
      const newDataStr = JSON.stringify(newData);
      fs.writeFile(filePath, newDataStr, wErr => {
        if (wErr) {
          onWriteError?.(wErr);
          return;
        }
        onWriteOver?.();
      });
    }
  });
};

const jsonCRUDGenerator = dbFile => {
  const C = (req, res, next) => {
    const newItem = req.body;
    if (!fs.existsSync(dbFile)) {
      fs.writeFileSync(dbFile, '[]');
    }
    fs.readFile(dbFile, 'utf8', (err, data) => {
      if (err) {
        res.send({
          data: [],
          code: 0,
          msg: err,
        });
        return;
      }
      let newData = null;
      if (data) {
        newData = JSON.stringify([...JSON.parse(data), newItem]);
      } else {
        newData = JSON.stringify(newItem);
      }
      fs.writeFile(dbFile, newData, wErr => {
        if (wErr) {
          res.send({
            data: [],
            code: 0,
            msg: wErr,
          });
          return;
        }
        res.send({
          data: newItem,
          code: 1,
          msg: '',
        });
      });
    });
  };

  const R = (req, res, next) => {
    if (!fs.existsSync(dbFile)) {
      fs.writeFileSync(dbFile, '[]');
    }
    fs.readFile(dbFile, 'utf8', (err, data) => {
      if (err) {
        res.send({
          data: [],
          code: 0,
          msg: err,
        });
        return;
      }
      res.send({
        data: JSON.parse(data),
        code: 1,
        msg: '',
      });
    });
  };

  const U = (req, res, next) => {
    const record = req.body;
    const recordID = record?.id;
    if (!recordID) {
      res.send({
        data: [],
        code: 0,
        msg: '非法ID',
      });
      return;
    }
    updateDBFile(dbFile, {
      onReadError: err => {
        res.send({
          data: [],
          code: 0,
          msg: err,
        });
      },
      onWriteError: err => {
        res.send({
          data: [],
          code: 0,
          msg: err,
        });
      },
      onReadOver: data => {
        const target = data.find(i => i.id === recordID);
        if (target) {
          Object.assign(target, record);
          return data;
        }
        return false;
      },
      onWriteOver: () => {
        res.send({
          code: 1,
          msg: '',
        });
      },
    });
  };

  const D = (req, res, next) => {
    const record = req.body;
    const recordID = record?.id;
    if (!recordID) {
      res.send({
        data: [],
        code: 0,
        msg: '非法ID',
      });
      return;
    }

    updateDBFile(dbFile, {
      onReadError: err => {
        res.send({
          data: [],
          code: 0,
          msg: err,
        });
      },
      onWriteError: err => {
        res.send({
          data: [],
          code: 0,
          msg: err,
        });
      },
      onReadOver: data => {
        const removeTarget = data.find(i => i.id === recordID);
        if (!data.length || !removeTarget) {
          res.send({
            data: [],
            code: 0,
            msg: '无效任务ID',
          });
          return false;
        }
        return data.filter(i => i.id !== recordID);
      },
      onWriteOver: () => {
        res.send({
          code: 1,
          msg: '',
        });
      },
    });
  };

  return { C, R, U, D };
};

module.exports = { updateDBFile, jsonCRUDGenerator };
